"use strict ";
/**
 * 前端核心函数
 * 37798955@qq.com
 */
/**字符串替换
 * @param {Object} reallyDo
 * @param {Object} replaceWith
 * @param {Object} ignoreCase
 */
String.prototype.replaceAll = function(reallyDo, replaceWith, ignoreCase) {
	if (!RegExp.prototype.isPrototypeOf(reallyDo)) {
		return this.replace(new RegExp(reallyDo, (ignoreCase ? "gi" : "gm")), replaceWith);
	} else {
		return this.replace(reallyDo, replaceWith);
	}
};
/**
 * 盘点字符串开始于 
 * @param {Object} str 开始于 
 */
String.prototype.startWith = function(str) {
	if (str == null || str == "" || this.length == 0 || str.length > this.length)
		return false;
	if (this.substr(0, str.length) == str)
		return true;
	else
		return false;
	return true;
};
/**
 * 左侧补n个0
 * @param {Object} length
 */
String.prototype.padLeft = function(length) {
	var a = [];
	for (var i = this.length; i < length; i++) {
		a.push("0");
	}
	a.push(this);
	return a.join("");
};
/**
 * 解析jsonstring  成 对象实例
 * @param {Object} length
 */
String.prototype.parse = function(length) {
	try {
		return JSON.parse(this);
	} catch (e) {
		return null;
	}
}
//两端去空格函数  
String.prototype.trim = function() {
	return this.replace(/(^\s*)|(\s*$)/g, "");
}
/**
 * 保留精度
 * @param {Object} digit 精度位数
 */
Number.prototype.digit = function(digit) {
	var m = Math.pow(10, digit);
	return parseInt(this * m, 10) / m;
};
Date.prototype.addMonths = function(mons) {
	var date = new Date(this);
	date.setMonth(date.getMonth() + mons);
	return date;
};
Date.prototype.addDays = function(days) {
	var date = new Date(this);
	date.setDate(date.getDate() + days);
	return date;
};
Date.prototype.format = function(fmt) {
	if (fmt == null || fmt == '')
		fmt = 'yyyy-MM-dd hh:mm:ss'
	var d = new Date(this);
	var o = {
		"M+": d.getMonth() + 1, //月 
		"d+": d.getDate(), //日 
		"h+": d.getHours(), //时 
		"m+": d.getMinutes(), //分 
		"s+": d.getSeconds(), //秒 
		"q+": Math.floor((d.getMonth() + 3) / 3), //季度
		"S": d.getMilliseconds() //毫秒 
	};
	if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (d.getFullYear() + "").substr(4 - RegExp.$1.length));
	for (var k in o)
		if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[
			k]).substr(("" + o[k]).length)));
	return fmt;
};
/**
 * 转成日期数值格式
 */
Date.prototype.toDateNum = function() {
	var D = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09'];
	var d = new Date(this);

	return [d.getFullYear(),
		D[d.getMonth() + 1] || d.getMonth() + 1,
		D[d.getDate()] || d.getDate()
	].join('')
};
/**
 * 转成时间数值格式
 */
Date.prototype.toTimeNum = function() {
	var D = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09'];
	var d = new Date(this);
	return [D[d.getHours()] || d.getHours(),
		D[d.getMinutes()] || d.getMinutes(),
		D[d.getSeconds()] || d.getSeconds(),
		d.getMilliseconds().toString().padLeft(4)
	].join('');
};


/**
 * 功能:实现VBScript的DateAdd功能.
 *   参数:interval,字符串表达式，表示要添加的时间间隔.
 *   参数:number,数值表达式，表示要添加的时间间隔的个数.
 *   返回:新的时间对象.
 * @param {Object} interval 类型 年y 季度q 月M 周w 天 d 小时h 分钟 m 秒 s 默认：天
 * @param {Object} number 加数
 */
Date.prototype.add = function(interval, number) {
	var d = this;
	switch (interval) {
		case "y":
			d.setFullYear(d.getFullYear() + number);
			return d;
		case "q":
			d.setMonth(d.getMonth() + number * 3);
			return d;
		case "M":
			d.setMonth(d.getMonth() + number);
			return d;
		case "w":
			d.setDate(d.getDate() + number * 7);
			return d;
		case "h":
			d.setHours(d.getHours() + number);
			return d;
		case "m":
			d.setMinutes(d.getMinutes() + number);
			return d;
		case "s":
			d.setSeconds(d.getSeconds() + number);
			return d;
		default:
			d.setDate(d.getDate() + number);
			return d;
	}
};


//千万不能给Map 和 arry 对象的 prototype添加方法 会影响到 for（ in）语法
/**
 * 判断函数
 */

(function(e, t) {
	if ("object" == typeof exports && "object" == typeof module) module.exports._IS = t();
	else if ("function" == typeof define && define.amd) define(t);
	else e._IS = t(); //对象
})(this, function() {
	var _IS = {};
	var gettype = Object.prototype.toString;
	_IS.isType = function(o) {
		return gettype.call(o);
	}
	_IS.isMap = function(o) {
		return gettype.call(o) == "[object Object]";
	}
	_IS.isArray = function(o) {
		return gettype.call(o) == "[object Array]" || gettype.call(o) == "[object Arguments]";
	}
	_IS.isArguments = function(o) {
		return gettype.call(o) == "[object Arguments]";
	}
	_IS.isFun = function(o) {
		return gettype.call(o) == "[object Function]";
	}
	_IS.isNULL = function(o) {
		return gettype.call(o) == "[object Null]";
	}
	_IS.isUndefined = function(o) {
		return gettype.call(o) == "[object Undefined]";
	}
	_IS.isNum = function(o) {
		return gettype.call(o) == "[object Number]";
	}
	_IS.isString = function(o) {
		return gettype.call(o) == "[object String]";
	}
	_IS.isBool = function(o) {
		return gettype.call(o) == "[object Boolean]";
	}
	_IS.isEmpty = function(obj) {
		return (obj === undefined || obj === null) ? true : false;
	}
	_IS.isEmptyStr = function(obj) {
		return (obj === undefined || obj === null || obj == "" || obj == "null") ? true : false;
	}
	_IS.isEmptyMap = function(e) {
		if (e == undefined || e == null)
			return true;
		for (var t in e)
			return false;
		return true;
	}
	_IS.isEmptyArray = function(arr) {
		if (arr = undefined || _IS.isArray(arr) || arr.length == 0)
			return true;
		else
			return false;
	}


	_IS.checkEmail = function(email) {
		email = email || '';
		return (email.length > 3 && email.indexOf('@') > -1);
	};
	_IS.checkNumber = function(input) {
		var pattern = /^[0-9]+([.]{1}[0-9]{1,2})?$/;
		if (pattern.test(input)) {
			return true;
		} else {
			alert("请输入数值!");
			return false;
		}
	}
	return _IS;
});
(function(e, t) {
	if ("object" == typeof exports && "object" == typeof module) module.exports._Fun = t();
	else if ("function" == typeof define && define.amd) define(t);
	else e._Fun = t(); //对象
})(this, function() {
	var f = {
		o: {}, //万能对象类
		f: {},//函数类
		a: {}, //数组类型
		m: {}, //map对象类
		d: {}, //日期类
		n: {}, //数值类
		s: {}, //字符类
		pr: {} //打印类		
	};
	/** 
	 * 加减yyyymm 年月
	 * @param {Object} monnum 格式：yyyymm 年月
	 * @param {Object} num 正数：添加，负数：减少
	 */
	f.n.addMonnum = function(monnum, num) {
		var ym = new Number(monnum)
		var y = parseInt(ym / 100); //2017
		var m = ym % 100; //09
		var cnt = parseInt(num / 12);
		var mnt = num % 12;
		y = y + cnt;
		if (mnt < 0) {
			y = y - 1;
			m = m + (12 + mnt);
		} else {
			m = m + mnt;
		}
		if (m > 12) {
			y = y + 1;
			m -= 12;
		}
		return (y * 100 + m).toString();
	};

	/**放大
	 * @param {Object} f
	 * @param {Object} n n如果小于10  10^n  如果大于10 就是
	 */

	f.n.Zoomin = function(f, n) {
		return f * n;
	};

	/**缩小
	 * @param {Object} f
	 * @param {Object} n
	 */

	f.n.Zoomout = function(f, n) {
		return f / n;
	};
	/**左侧补0
	 * @param {Object} obj
	 * @param {number} length
	 */
	f.s.padLeft = function(obj, length) {
		return obj.toString().padLeft(length);
	};


	/**
	 * 获取
	 */
	f.s.getGuid = function() {
		var d = new Date().getTime();
		var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
			var r = (d + Math.random() * 16) % 16 | 0;
			d = Math.floor(d / 16);
			return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
		});
		return uuid;
	}
  f.d.timestamp=function () {
		return new Date().getTime();
	}
  f.s.timestamp=function () {
			var mydate = new Date;
			return  mydate.getFullYear() + (mydate.getMonth() + 1) + '' + mydate.getDate() + mydate.getHours() +
				mydate.getMinutes() + mydate.getSeconds() + mydate.getMilliseconds() + Math.round(Math.random() * 10000);
	}
	/**
	 * 把有分隔符的字符串转成数组或者对象
	 * 如果已经是数组或者对象则不用转化
	 * @param {String ，Array ，Map} obj 
	 */
	function split(obj, sp) {
		var props = null;
		sp = (sp == undefined || sp == null) ? "," : sp;
		if (_IS.isEmpty(obj)) return null;
		if (_IS.isString(obj))
			props = obj.split(sp);
		else
			props = obj;
		return props;
	}
	f.s.split = split;
	/**
	 * 测试打印json对象
	 * @param {Object} data
	 * @param {Object} note
	 */
	f.pr.json = function(data, note) {
		var s = JSON.stringify(data);
		if (note == null)
			console.log(s)
		else
			console.log(note, s)
	};
	/**
	 * 测试打印map对象
	 * @param {Object} data
	 * @param {Object} note
	 */
	f.pr.map = function(m) {
		for (var i in map) {
			console.log(i, JSON.stringify(map[i]));
		}
	};

	function equal(a, b) {
		if ((null == a && null == b) || (undefined == a && undefined == b)) return true;
		var classNameA = toString.call(a),
			classNameB = toString.call(b);
		if (classNameA == '[object Function]') return false;
		switch (classNameA) {
			case '[object RegExp]':
			case '[object String]':
				//进行字符串转换比较
				return '' + a === '' + b;
			case '[object Number]':
				//进行数字转换比较,判断是否为NaN
				if (+a !== +a) {
					return +b !== +b;
				}
				//判断是否为0或-0
				return +a === 0 ? 1 / +a === 1 / b : +a === +b;
			case '[object Date]':
			case '[object Boolean]':
				return +a === +b;
		}
		if (classNameA == '[object Array]') {
			for (var i = 0; i < a.length; ++i) {
				if (!equal(a[i], b[i])) return false;
			}
			return true;
		}
		if (classNameA == '[object Object]') {
			for (var i in a) {
				if (!equal(a[i], b[i])) return false;
			}
			return true;
		}
		return false;
	}
	/**
	 * 判断两个参数是否值相等
	 */

	f.o.equal = equal;

	function change2(a, a1) {
		if (_IS.isEmpty(a) || _IS.isEmpty(a1)) return;
		var z;
		z = a;
		a = a1;
		a1 = z;
	}
	/**
	 * 交换两个变量值
	 */
	f.o.change = change2;
	/**
	 * 在数组arr1的第n位之前，插入arr2元素
	 * @param {Object} arr1 待插入的数组
	 * @param {Object} n  第n位之前
	 * @param {Object} arr2 插入arr2数组
	 */
	function insert(arr1, n, arr2) {
		if (arr2 == null || arr2 == undefined) return arr1;
		n = (n > arr1.length) ? arr1.length : (n < 0) ? arr1.length + n : n;
		for (var i = arr2.length - 1; i >= 0; i--) {
			arr1.splice(n, 0, arr2[i]);
		}
		return arr1;
	}
	f.a.insert = insert;
	/**
	 * 移动数组中的一个元素从i 到 n位后面
	 * @param {Object} arr1 数组
	 * @param {Object} i 移动前的开始位置
	 * @param {Object} n 移动前的目标位置之后
	 * @param {Object} len 移动元素个数
	 */
	function move(arr1, a, n, len) {
		if (len == null || len == undefined) return arr1;
		//var a = arr1.slice(i, i + len);
		if (a == n || a < 0 || len < 1 || len > arr1.length) return arr1;
		var b;
		if (a > n) {
			b = a;
			a = n;
			n = b;
		}
		if (a + len > n) return arr1;
		var k = n - a - len;
		for (var i = len - 1; i >= 0; i--) {
			for (var j = 0; j <= k; j++) {

				var z = a + i + j;
				change(arr1, z, z + 1);
			}
		}
		return arr1;
	}
	f.a.move = move;

	function change(arr1, a, a1) {
		if (_IS.isEmpty(arr1) || _IS.isEmpty(a) || _IS.isEmpty(a1) || _IS.isEmpty(arr1[a1]) || _IS.isEmpty(arr1[a]))
			return;
		var z
		z = arr1[a];
		arr1[a] = arr1[a1];
		arr1[a1] = z;
	}
	f.a.change = change;

	/**
	 * 交换数组 a位置和n位置的 元素 长度为len
	 * @param {Object} arr1
	 * @param {Object} a
	 * @param {Object} n
	 * @param {Object} len
	 */
	f.a.exchange = function(arr1, a, n, len) {
		if (len == null || len == undefined) return arr1;
		//var a = arr1.slice(i, i + len);
		if (a == n || a < 0 || len < 1 || len > arr1.length) return arr1;
		var b;
		if (a > n) {
			b = a;
			a = n;
			n = b;
		}
		if (a + len > n) return arr1;
		var k = n - a;
		for (var i = 0; i < len; i++) {
			change(arr1, a + i, n + i);
		}
		return arr1;

	}
	f.d.getStamp = function() {
		return new Date().getTime();
	}
	/**
	 * 拼接数组（不平面化）直接用join
	 * 拼接数组（只对第二层平面化） 用concat ,为空的不丢弃
	 * 参数个数可变
	 * a=[1,2,3] ,b=[3，4]
	 * c.concat(a,b) =[1,2,3,3,4]
	 */
	f.a.concat = function() {
		var arr = [];
		for (var i = 0; i < arguments.length; i++) {
			var item = arguments[i];
			if (_IS.isArray(item)) {
				for (var j = 0; j < item.length; j++) {
					arr.push(item[j]);
				}
			} else {
				if (_IS.isEmpty(item)) return [];
				arr.push(item);
			}
		}
		return arr;
	}
	/**
	 * 适用于 【字符串，字符串】类型
	 * 不剔除空值，
	 * @param {Object} arr
	 */
	f.a.distinct = function(arr) {
		var arr1 = []
		for (var i = 0; i < arr.length; i++) {
			//if (_IS.isEmpty(arr[i])) continue;
			var flag = true;
			for (var j = 0; j < arr1.length; j++) {
				if (equal(arr1[j], arr[i])) {
					flag = false;
					break;
				}
			}
			if (flag)
				arr1.push(arr[i])
		}
		return arr1;
	}
	/**
	 * 删除空的元素
	 */
	f.a.trim = function(arr1) {
		if (arr1 == null || arr1.length < 1) return [];
		var arr = [];
		for (var i = 0; i < arr1.length; i++) {
			if (arr1[i] == null || arr1[i] == undefined || arr1[i] == "") {
				continue;
			}
			arr.push(arr1[i]);
		}
		return arr;
	};
	/**
	 * 查找数组中的位置
	 * @param {Object} arr 待匹配的数组
	 * @param {Object} obj 匹配的对象
	 * find() 在ie11 之前不支持
	 */
	f.a.indexOf = function(arr, obj) {
		for (var i = 0; i < arr.length; i++) {
			if (equal(arr[i], obj)) return i;
		}
		return -1;
	};

	f.a.exist = function(arr, obj) {
		if (arr.indexOf(obj) > -1) return true;
		return false;
	};

	function arrput(arr, key) {
		if (_IS.isEmpty(arr))
			arr = [];
		for (var i = 0; i < arr.length; i++) {
			if (arr[i] == key) {
				return;
			}
		}
		arr.push(key);
		return arr;
	}
	f.a.put = arrput;
	/**
	 * 深度克隆
	 * @param {Object} obj 待克隆的map对象
	 * @param {Object} attrs 对于map类型的对象 可以限定克隆的属性 ，数组格式
	 */
	function clone(obj, attrs) {
		if (undefined == obj || null == obj) return null;
		if (obj instanceof Date) {
			var copy = new Date();
			copy.setTime(obj.getTime());
			return copy;
		}
		if (obj instanceof Array) {
			var copy = [];
			for (var i = 0; i < obj.length; ++i) {
				copy.push(clone(obj[i], attrs));
			}
			return copy;
		}
		if (obj instanceof Object) {
			var copy = {};
			if (attrs == null) {
				for (var attr in obj) {
					copy[attr] = obj[attr];
				}
			} else {
				for (var a = 0; a < attrs.length; a++) {
					copy[attrs[a]] = obj[attrs[a]];
				}
			}
			return copy;
		}
		return obj;
	}
	f.o.clone = clone;

	/**
	 * 对比两个Map对象的特定属性 判断是否相等
	 * @param {Map} obj1 Map
	 * @param {Map} obj2 Map
	 * @param {Array} cols  待对比的键
	 */
	f.m.equal = function(obj1, obj2, cols) {
		var keys = split(cols);
		if (keys == null) return false;
		for (var i = 0; i < keys.length; i++) {
			var field = keys[i];
			if (!equal(obj1[field], obj2[field])) {
				return false;
			}
		}
		return true;
	};

	//对象合并可以使用 Object.assign函数

	/**
	 * 根据属性,截取object对象的部分属性 生成新的对象
	 * @param {Object} object
	 * @param {String，Array} cols 过滤字段集合，如果为空，那么不过滤
	 * @return {Object}  返回对象
	 */
	function section(arr) {
		var n1 = {};
		if (_IS.isEmpty(arr)) return {};
		else if (_IS.isMap(arr)) return arr;
		else if (_IS.isArray(arr)) {
			object = arr[0];
			cols = arr[1];

			if (_IS.isEmptyStr(cols)) return object;
			var props = split(cols);
			for (var i = 0; i < props.length; i++) {
				n1[props[i]] = object[props[i]];
			}
			console.log(object, cols, props, "n1:", n1)
			return n1;
		} else return {};
	}
	f.m.section = section;
	/**合并两个对象，是merge的基础 ，兼容低版本浏览器Es5
	 * ES6 对象提供了 Object.assign()这个方法
	 * @param {Object} a
	 * @param {Object} b
	 */

	function assign(a, b) {
		var n1 = {};
		if (_IS.isEmpty(b)) {
			if (_IS.isEmpty(a))
				return {};
			else {
				return a;
			}
		} else {
			for (var k in b) {
				a[k] = b[k];
			}
			return a;
		}
	}
	f.m.assign = assign;

	/**
	 * 合并o1和o2 生成新的对象,可以只选择抽取o1和o2中的部分字段
	 * @param {Array[Object]} 待合并对象集合 ，
	 */
	function merge() {
		var a = null;
		if (arguments.length == 1) return arguments[0];
		else if (arguments.length < 1) return {};
		else {
			var a = section(arguments[0]);
			var b = a;
			for (var i = 1; i < arguments.length; i++) {
				a = section(arguments[i]);
				assign(b, a);
			}
		}
		return b;
	}
	f.m.merge = merge;

	/**
	 *  把b值覆盖写入a
	 */
	f.m.over = function(a, b) {		
		if (_IS.isEmpty(b)||_IS.isEmpty(a)) {		
				return ;		
		} else {
			for (var k in a) {
				if (b[k])	
					a[k] = b[k];				
			}			
		}
	}	
	//异步转同步的函数,信号灯法,效率比较慢,中间会有等待,未测试
	function signExec(arrfun,sign1) {
		var sign2,flag=1;
		if (_IS.isArray(arrfun)&&arrfun.length>0){
			if (sign1){				
				sign2=sign1.slice(1);	
				flag=sign1[0];
			}else{
				sign2=new Array(arrfun.length-1);		
			}		
			if (flag&&_IS.isFun(arrfun[0])) {
					arrfun[0]();
					signExec(funs.slice(1),sign2);
			}else{
				setTimeout(function() {
					signExec(funs,sign1);
				}, 3);
			}		
		}
	}
	f.f.signExec=signExec;
	//简易版的异步转同步,根据whereFunc执行结果是否为true,判断是否需要执行回调函数callback,未测试
	function synExec(whereFunc, callback, ms) {
		var flag = false;
		if (whereFunc && whereFunc()) {
			if (callback)
				callback();
		} else {
			if (ms == null) ms = 1;
			setTimeout(function() {
				synExec(whereFunc, callback, ms);
			}, ms);
		}
	}
	f.f.synExec=synExec;
	return f;
	
});
/**
 * 异步转同步函数
 * 用法 :
 * 1/ var fs=_Syn(方法(),....);
 * 2/ fs.start();
 */
(function(e, t) {
	if ("object" == typeof exports && "object" == typeof module) module.exports._Syn = t;
	else if ("function" == typeof define && define.amd) define(t);
	else e._Syn = t; //对象
})(this, function() {
	var _funs = []; //函数
	if (arguments.length > 0)
		_funs = arguments;
	this.then = function(t) {
		_funs.push(t);
	};
	/*按顺序调用函数,但是每个函数第一个入参也是函数对象,函数对象被调用时,继续执行下一个函数,否则不执行*/
	function callw(funs) {
		if (funs.length == 0) return;
		if (_IS.isFun(funs[0])) {
			funs[0](function() {
				funs1 = funs.slice(1);
				callw(funs1);
			});
		}
	};
	//按顺序调用函数,
	function call(funs) {
		if (funs.length == 0) return;
		if (_IS.isFun(funs[0])) {
			funs[0]();
			funs1 = funs.slice(1);
			call(funs1);
		}
	};
	/**
	 * 开始按照从右到左的顺序执行函数集合
	 */
	this.start = function() {
		_funs = _Fun.a.concat(_funs, arguments)
		_funs.reverse();
		call(_funs);
	};	
	/**
	 * 开始按照从右到左的顺序执行函数集合 ，执行的时候依赖 next()的调用
	 * 用时 
	 */
	this.startw = function() {
		_funs = _Fun.a.concat(_funs, arguments)
		_funs.reverse();
		callw(_funs);
	};
	return this;
});


/**
 * 建模工具对象，专门用于建模 
 * 模型定义 可以根据配置 mdconf 动态改变
 * 
 */
(function(e, t) {
	if ("object" == typeof exports && "object" == typeof module) module.exports._FD = new t();
	else if ("function" == typeof define && define.amd) define(t);
	else e._FD = new t(); //静态函数库
})(this, function() {
	/**
	 * types %%type1 替换项
	 * auto %%auto 替换项
	 * notnull %%notnull 替换项
	 * note %%note 替换项
	 */
	var mdconf = {
		types: function(lx) {
			return (lx.startWith('l') || lx.startWith('i')) ? "INTEGER" : (lx.startWith('dt') ? "NUMERIC" : "TEXT")
		},
		get: function(lx) {
			return (lx.startWith('l') || lx.startWith('i')) ? "getN" : "getV"
		},
		put: function(lx) {
			return (lx.startWith('l') || lx.startWith('i')) ? "putN" : "putV"
		},
		auto: {
			pt: "",
			zz: "", //primary key  AUTOINCREMENT
			sj: "",
			uu: ""
		},
		notnull: ["", "not null"],
		common: function(nt) {
			return _IS.isEmpty(nt) ? "" : ("comment '" + nt + "'");
		},
		title: function(zh) {
			return zh;
		}
	};
	this.config = function(obj) {
		Object.assign(mdconf, obj);
	};
	/**
	 * 根据表的字段模型mode 解析表table的字段集合
	 * @param {Object} table
	 * @param {Object} mode
	 * @param {Object} sp 分隔符
	 * @param {String} effcols 有效字段 {"字段1":[value,..],"字段1":[value,..]}
	 * @param {Object} isfilter  是否过滤模式 true 过滤模式时 以有效字段作为属性集输出，false 非过滤模式，输出所有字段
	 */
	function merge(table, mode, sp, effcols, isfilter) {
		if (table) {
			var tablename = table.tablename;
			var fds = table.fields; //alert(JSON.stringify(fds))
			if (_IS.isEmptyStr(effcols))
				effcols = undefined;
			else if (_IS.isString(effcols)) {
				effcols = JSON.parse(effcols);
			}
			var eachs = fds;
			if (isfilter) eachs = effcols;
			var s;

			var arr = [];
			for (var col in eachs) {
				if (!(col in fds)) continue;
				var zh = fds[col][0] || "";
				var lx = fds[col][1] || 't';
				var ky = fds[col][2] || "pt";
				var nnl = fds[col][3] || 0;
				var def = (effcols) ? effcols[col] : fds[col][4];
				var note = fds[col][5] || "";
				var s = mode.replaceAll("%%field0", col);
				s = s.replaceAll("%%title", mdconf.title(zh)); //中文标题
				s = s.replaceAll("%%note", mdconf.common(note)); //注释			
				s = s.replaceAll("%%auto", mdconf.auto[ky]);
				s = s.replaceAll("%%notnull", mdconf.notnull[nnl]);
				var d1, d2, d3;
				if (_IS.isEmptyStr(def)) {
					d1 = "null";
					d2 = "null";
					d3 = "null";
				} else {
					if (lx.startWith('l') || lx.startWith('i')) { //数值格式
						d1 = "default " + def;
						d2 = def;
						d3 = def;
					} else {
						d1 = "default \'" + def + "\'";
						d2 = "\"" + def + "\"";
						d3 = "'" + def + "'";
					}

				}
				s = s.replaceAll("%%type0", lx);
				s = s.replaceAll("%%type1", mdconf.types(lx));
				s = s.replaceAll("%%default", d1);
				s = s.replaceAll("%%value0", d3);
				s = s.replaceAll("%%value", d2);
				s = s.replaceAll("%%getV", mdconf.get(lx));
				s = s.replaceAll("%%putV", mdconf.put(lx));
				s = s.replaceAll("%%tbname", tablename); //表名
				arr.push(s);
			}
			if (sp) {
				s = arr.join(sp);
			} else {
				s = arr.join("");
			}
			return s;
		}
		return "";

	}


	/**
	 * 根据表的字段模型mode 解析表table的字段集合
	 * @param {Object} table
	 * @param {Object} mode
	 * @param {Object} sp 分隔符
	 * @param {String} effcols 有效字段 {"字段1":[value,..],"字段1":[value,..]}
	 */
	this.mergeFields = merge;
	/**
	 * 格式化数组，成新的字符串
	 * @param {Object} fields
	 * @param {Object} mode
	 * @param {Object} sp
	 */
	this.mergeArr = function(fields, mode, sp) {
		var arr = [];
		for (var i = 0; i < fields.length; i++) {
			arr.push(mode.replaceAll("$1", fields[0]))
		}
		if (sp) {
			s = arr.join(sp);
		} else {
			s = arr.join("");
		}
		return s;
	}
	this.mergeAnd = function(table, col, symbvalue) {
		var tablename = table.tablename;
		var fds = table.fields; //alert(JSON.stringify(fds))
		if (!(col in fds) || _IS.isEmpty(symbvalue)) return "";
		var lx = fds[col][1] || 't';
		var def = (symbvalue) ? symbvalue[1] : fds[col][4];
		var mode = "#1 #2 #4#3#5";
		var s = mode.replaceAll("#1", col);
		var m = "=",
			mbegin = "",
			mend = "";
		var n = symbvalue[0];
		if (n == '=' || n == '>' || n == '<' || n == '>=' || n == '<=' || n == 'not')
			m = n;
		else if (n.indexOf('%') > 0) {
			m = 'like';
			if (n.indexOf('%_') > 0)
				mbegin = "'%";
			if (n.indexOf('_%') > 0)
				mend = "%'";
		} else if (n.indexOf('in') > 0) {
			m = 'in';
			mbegin = "(";
			mend = ")";
		} else if (n.indexOf('exist') > 0) {
			m = 'exists';
			mbegin = "(";
			mend = ")";
		}
		s = s.replaceAll("#2", m); //运算符
		s = s.replaceAll("#4", mbegin); //开始边界
		s = s.replaceAll("#5", mend); //结束边界
		var d3, d5;
		if (_IS.isEmptyStr(def)) {
			d3 = "0";
			d5 = "null";
		} else {
			d3 = def;
			d5 = "'" + def + "'";
		}
		if (lx.startWith('l') || lx.startWith('i')) { //数值格式
			s = s.replaceAll("#3", d3);
		} else { //其他格式		
			s = s.replaceAll("#3", d5);
		}
		return s;
	}


});
